﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Globalization;
using System.IO;
using PMC;

namespace PMCgui
{
    /// <summary>
    /// Delivers right language
    /// </summary>
    [DataContract]
    class Language
    {
        private static Language _instance;
        public static Language Instance
        {
            get
            {
                if (_instance == null)
                {
                    if (CultureInfo != null && !CultureInfo.Equals(Default))
                    {
                        string filename = PMC.Properties.Settings.Default.SettingsFolder + "/" + CultureInfo.TwoLetterISOLanguageName + ".lang";
                        if (!System.IO.File.Exists(filename))
                            throw new FileNotFoundException("Language");

                        _instance = PMC.Global.XMLDeserialize<Language>(filename);
                    }
                    else
                    {
                        _instance = new Language();
                    }
                }
                return _instance;
            }
        }

        public static CultureInfo Default = CultureInfo.GetCultureInfo("en");

        private static CultureInfo _cultureInfo = Default;
        public static CultureInfo CultureInfo
        {
            get { return _cultureInfo; }
            set { _cultureInfo = value; }
        }

        public static void Reset()
        {
            _instance = null;
        }

        /// <summary>
        /// Yes
        /// </summary>
        [DataMember]
        public string Yes = "Yes";
        /// <summary>
        /// No
        /// </summary>
        [DataMember]
        public string No = "No";
        /// <summary>
        /// Cancel
        /// </summary>
        [DataMember]
        public string Cancel = "Cancel";
        /// <summary>
        /// Ok
        /// </summary>
        [DataMember]
        public string Ok = "Ok";

        /// <summary>
        /// File
        /// </summary>
        [DataMember]
        public string File = "File";
        /// <summary>
        /// Settings
        /// </summary>
        [DataMember]
        public string Settings = "Settings";
        /// <summary>
        /// Website
        /// </summary>
        [DataMember]
        public string Website = "Website";
        /// <summary>
        /// Perform Update
        /// </summary>
        [DataMember]
        public string PerformUpdate = "Perform Update";
        /// <summary>
        /// Options
        /// </summary>
        [DataMember]
        public string Options = "Options";
        /// <summary>
        /// Url
        /// </summary>
        [DataMember]
        public string Url = "Url";
        /// <summary>
        /// Connection
        /// </summary>
        [DataMember]
        public string Connection = "Connection";
        /// <summary>
        /// About
        /// </summary>
        [DataMember]
        public string About = "About";
        /// <summary>
        /// View Log
        /// </summary>
        [DataMember]
        public string ViewLog = "View Log";
        /// <summary>
        /// Start
        /// </summary>
        [DataMember]
        public string Start = "Start";

        /// <summary>
        /// Are you sure you want to delete this expression?
        /// </summary>
        [DataMember]
        public string DeleteExpression = "Are you sure you want to delete this expression?";
        /// <summary>
        /// Delete
        /// </summary>
        [DataMember]
        public string Delete = "Delete";
        /// <summary>
        /// {0}! This link will {1} be found during search."
        /// </summary>
        [DataMember]
        public string ThisLinkWillBeFoundDuringSearch = "{0}! This link will {1} be found during search.";
        /// <summary>
        /// Error reading log.
        /// </summary>
        [DataMember]
        public string ErrorReadingLog = "Error reading log.";
        /// <summary>
        /// Mail
        /// </summary>
        [DataMember]
        public string Mail = "Mail";
        /// <summary>
        /// Upgrade
        /// </summary>
        [DataMember]
        public string Upgrade = "Upgrade";
        /// <summary>
        /// Language
        /// </summary>
        [DataMember]
        public string strLanguage = "Language";

        /// <summary>
        /// Setting(s) changed, do you want to save these settings?
        /// </summary>
        [DataMember]
        public string SettingsChangedSave = "Setting(s) changed, do you want to save these settings?";
        /// <summary>
        /// Save settings
        /// </summary>
        [DataMember]
        public string SaveSettings = "Save settings";

        /// <summary>
        /// An error occured fetching urls. Exception information:
        /// </summary>
        [DataMember]
        public string ErrorFetchingEmails = "An error occured fetching urls. Exception information:";
        /// <summary>
        /// UrlCollector already active!
        /// </summary>
        [DataMember]
        public string UrlCollectionActive = "UrlCollector already active!";
        /// <summary>
        /// Url not wellformed, please enter a correct url.
        /// </summary>
        [DataMember]
        public string UrlNotWellformed = "Url not wellformed, please enter a correct url.";

        /// <summary>
        /// There is a new update availlable, would you like to update?
        /// </summary>
        [DataMember]
        public string UpdateAvailable = "There is a new update availlable, would you like to update?";
        /// <summary>
        /// Update found
        /// </summary>
        [DataMember]
        public string UpdateFound = "Update found";
        /// <summary>
        /// You have the most recent version of PaidMailClicker!
        /// </summary>
        [DataMember]
        public string MostRecentVersion = "You have the most recent version of PaidMailClicker!";
        /// <summary>
        /// No update found
        /// </summary>
        [DataMember]
        public string NoUpdateFound = "No update found";
        /// <summary>
        /// Please try again!
        /// </summary>
        [DataMember]
        public string PleaseTryAgain = "Please try again!";

        /// <summary>
        /// Connection error, please check your connection to internet.
        /// </summary>
        [DataMember]
        public string PleaseCheckConnection = "Connection error, please check your connection to internet.";

        /// <summary>
        /// An error occured!
        /// </summary>
        [DataMember]
        public string ErrorOccured = "An error occured!";

        /// <summary>
        /// PMC Session Files
        /// </summary>
        [DataMember]
        public string PMCSessionFiles = "PMC Session Files";
        /// <summary>
        /// Expressions file
        /// </summary>
        [DataMember]
        public string PMCExpressionFile = "Expressions file";
        /// <summary>
        /// Websites file
        /// </summary>
        [DataMember]
        public string PMCWebsiteFile = "Websites file";

        /// <summary>
        /// One or more fields are whitespaced or empty. Or not in a valid format.
        /// </summary>
        [DataMember]
        public string FieldWhiteSpacedOrFormat = "One or more fields are whitespaced or empty. Or not in a valid format.";
        /// <summary>
        /// Are you sure you want to delete the selected website?
        /// </summary>
        [DataMember]
        public string ConfirmDeleteWebsites = "Are you sure you want to delete the selected website?";

        ///////////////////////////////////////////////////// ProgressControl
        /// <summary>
        /// Add
        /// </summary>
        [DataMember]
        public string Add = "Add";
        /// <summary>
        /// Date
        /// </summary>
        [DataMember]
        public string Date = "Date";
        /// <summary>
        /// Update Links
        /// </summary>
        [DataMember]
        public string UpdateLinks = "Update Links";
        /// <summary>
        /// Add Browser
        /// </summary>
        [DataMember]
        public string AddBrowser = "Add Browser";
        /// <summary>
        /// Message
        /// </summary>
        [DataMember]
        public string Message = "Message";
        /// <summary>
        /// Est. Time left: {0}
        /// </summary>
        [DataMember]
        public string EstimatedTimeLeft = "Est. Time left: {0:hh\\:mm\\:ss}";
        /// <summary>
        /// Links left: {1}
        /// </summary>
        [DataMember]
        public string LinksLeft = "Links left: {1}";

        ////////////////////////////////////////////////////// WebBrowserControl
        /// <summary>
        /// Statistics
        /// </summary>
        [DataMember]
        public string Statistics = "Statistics";

        ////////////////////////////////////////////////////// Options
        /// <summary>
        /// Global
        /// </summary>
        [DataMember]
        public string Global = "Global";
        /// <summary>
        /// Url Collection
        /// </summary>
        [DataMember]
        public string UrlCollection = "Url Collection";
        /// <summary>
        /// URL Collector is the way the links will be collected.
        /// </summary>
        [DataMember]
        public string UrlCollectorExplained = "URL Collector is the way the links will be collected.";
        /// <summary>
        /// Expressions
        /// </summary>
        [DataMember]
        public string Expressions = "Expressions";
        /// <summary>
        /// Disable Protected Mode in Internet Explorer (May fix login/cookie problems in Vista/Win7)
        /// </summary>
        [DataMember]
        public string ProtectedModeExplained = "Disable Protected Mode in Internet Explorer (May fix login/cookie problems in Vista/Win7)";
        
        ///////////////////////////////////////////////////////////////// WebsitesTab
        /// <summary>
        /// Default Script
        /// </summary>
        [DataMember]
        public string DefaultScript = "Default Script";
        /// <summary>
        /// Add Website
        /// </summary>
        [DataMember]
        public string AddWebsite = "Add Website";
        /// <summary>
        /// Use
        /// </summary>
        [DataMember]
        public string Use = "Use";

        ////////////////////////////////////////////////////////////////// ExpressionsTab
        /// <summary>
        /// Add Expression
        /// </summary>
        [DataMember]
        public string AddExpression = "Add Expression";
        /// <summary>
        /// Add Exception
        /// </summary>
        [DataMember]
        public string AddException = "Add Exception";
        /// <summary>
        /// Test a URL
        /// </summary>
        [DataMember]
        public string TestAUrl = "Test a URL";

        /////////////////////////////////////////////////////////////////////// PluginInformationPanel
        /// <summary>
        /// Title: {0}{4}Description: {1}{4}Author: {2}{4}Version: {3}
        /// </summary>
        [DataMember]
        public string PluginInformationFormat = "Title: {0}{4}Description: {1}{4}Author: {2}{4}Version: {3}";

        /////////////////////////////////////////////////////////////////////// upgradeUserControl
        /// <summary>
        /// If you upgrated from an older version of PMC you can use this panel to migrate your old settings to this version.
        /// </summary>
        [DataMember]
        public string UpgradeExplanation = "If you upgrated from an older version of PMC you can use this panel to migrate your old settings to this version.";
        /// <summary>
        /// Import Websites
        /// </summary>
        [DataMember]
        public string ImportWebsites = "Import Websites";
        /// <summary>
        /// Import Expressions
        /// </summary>
        [DataMember]
        public string ImportExpressions = "Import Expressions";
        /// <summary>
        /// Import old websites. File in old versions located in the same directory as the program. Filename should be 'websites.ini'
        /// </summary>
        [DataMember]
        public string ImportWebsitesExplanation = "Import old websites. File in old versions located in the same directory as the program. Filename should be 'websites.ini'";
        /// <summary>
        /// Import epxressions of previous version. This file should also be located in the directory as the program. Filename should be 'exc.ini'
        /// </summary>
        [DataMember]
        public string ImportExpressionsExplanation = "Import epxressions of previous version. This file should also be located in the directory as the program. Filename should be 'exc.ini'";

        /////////////////////////////////////////////////////////////////////// waitDialog
        /// <summary>
        /// Please Wait
        /// </summary>
        [DataMember]
        public string PleaseWait = "Please Wait";

        /////////////////////////////////////////////////////////////////////// webbrowserMenuStrip
        /// <summary>
        /// Open Session
        /// </summary>
        [DataMember]
        public string OpenSession = "Open Session";
        /// <summary>
        /// Save Session
        /// </summary>
        [DataMember]
        public string SaveSession = "Save Session";
        /// <summary>
        /// Open File
        /// </summary>
        [DataMember]
        public string OpenFile = "Open File";

        ////////////////////////////////////////////////// LanguageUserControl
        /// <summary>
        /// You can load different language files with PMC, these files contain translations. You can help by contributing new translation for different languages or correct them.
        /// </summary>
        [DataMember]
        public string LanguageExplanation = "You can load different language files with PMC, these files contain translations. You can help by contributing new translation for different languages or correct them. New languages need to be placed in the Settings-folder in order to show up here.";
        /// <summary>
        /// Change Language
        /// </summary>
        [DataMember]
        public string ChangeLanguage = "Change Language";
        /// <summary>
        /// Create new language
        /// </summary>
        [DataMember]
        public string CreateLanguage = "Create new language";
        /// <summary>
        /// Create new from current translation
        /// </summary>
        [DataMember]
        public string CreateLanguageCurrent = "Create new from current translation";
        /// <summary>
        /// Help PMC with creating new translations! File names should be a two letter language name (ISO 639-1 format) with a *.lang extension.
        /// </summary>
        [DataMember]
        public string NewTranslationExplanation = "Help PMC with creating new translations! File names should be a two letter language name (ISO 639-1 format) with a *.lang extension.";
        
        //////////////////////////////////////////////////////////////// DatagridPanel
        /// <summary>
        /// This property has to be unique, another row exists with the same name!
        /// </summary>
        [DataMember]
        public string UniquePropertyDuplicate = "This property has to be unique, another row exists with the same name!";
        /// <summary>
        /// This property cannot be empty.
        /// </summary>
        [DataMember]
        public string PropertyEmpty = "This property cannot be empty.";
        /// <summary>
        /// This property is in an invalid format
        /// </summary>
        [DataMember]
        public string PropertyInvalidFormat = "This property is in an invalid format.";

        //////////////////////////////////////////// WebsiteForm /////////////////////////////////////
        public string FormatDuplicateName = "Name '{0}' must be unique!";

        /// <summary>
        /// Fields that weren't serialize fill them with the English translation
        /// </summary>
        /// <param name="context"></param>
        [OnDeserialized]  
        private void OnDeserialized(StreamingContext context)
        {
            var defaultObject = new Language();
            foreach (FieldInfo field in typeof(Language).GetFields())
            {
                var value = field.GetValue(this);
                if (value != null)
                    continue;

                var defaultValue = field.GetValue(defaultObject);
                field.SetValue(this, defaultValue);
            }
        }

        /// <summary>
        /// Generates a new editable language file with English as base
        /// </summary>
        /// <param name="file">Path to save the file to</param>
        public static void GenerateNewLanguageXML(string file)
        {
            PMC.Global.XMLSerialize(file, new Language());
        }

        /// <summary>
        /// Generates a editable language file with current language as base
        /// </summary>
        /// <param name="file">Path to save the file to</param>
        public void GenerateLanguageXML(string file)
        {
            PMC.Global.XMLSerialize(file, this);
        }

        public CultureInfo[] GetAvailableLanguages()
        {
            var files = Directory.GetFiles(PMC.Properties.Settings.Default.SettingsFolder, "*.lang");

            var languages = new List<CultureInfo>(files.Length + 1);
            languages.Add(Default);
            for (int i = 0; i < files.Length; i++)
            {
                var file = Path.GetFileName(files[i]) ?? string.Empty;
                if (file.Length < 2)
                    throw new FileLoadException(file);
                try
                {
                    var lang = CultureInfo.GetCultureInfo(file.Substring(0, 2));
                    if (lang.Equals(CultureInfo))
                        lang = CultureInfo;
                    languages.Add(lang);
                }
                catch (ArgumentException e)
                {
                    Log.Instance.AddException(e);
                }
            }
            return languages.ToArray();
        }
    }
}
